package opc.read.getAllGropItems;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import opc.read.utils.OpcServerUtil;
import org.jinterop.dcom.common.JIException;
import org.openscada.opc.lib.common.AlreadyConnectedException;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.common.NotConnectedException;
import org.openscada.opc.lib.da.DuplicateGroupException;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.browser.Branch;
import org.openscada.opc.lib.da.browser.FlatBrowser;
import org.openscada.opc.lib.da.browser.Leaf;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.LinkedHashMap;
import java.util.concurrent.Executors;

/**
 * @Description:
 * @author: liyuan
 * @data 2021-01-27 09:27
 */
public class GetGroupItemTrees {
    public static final LinkedHashMap<String, LinkedHashMap<String, String>> map = new LinkedHashMap<>(1000);

    public static void main(String[] args) throws DuplicateGroupException, NotConnectedException, JIException, IOException, AlreadyConnectedException {
        final ConnectionInformation ci = OpcServerUtil.connection();
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        server.connect();
        /** 获得OPC连接下所有的Group和Item */
        dumpTree(server.getTreeBrowser().browse(), 0);
        /** 获得OPC下所有的Item */
//        dumpFlat(server.getFlatBrowser());
        server.disconnect();
        final Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        String s = gson.toJson(map);
        System.out.println(s);
    }

    /**
     * 遍历Flat结构的所有Item值
     *
     * @param browser
     * @throws IllegalArgumentException
     * @throws UnknownHostException
     * @throws JIException
     */
    public static void dumpFlat(final FlatBrowser browser)
            throws IllegalArgumentException, UnknownHostException, JIException {
        for (String name : browser.browse()) {
            System.out.println(name);
        }
    }

    /**
     * 遍历Tree结构
     *
     * @param branch
     * @param level
     */
    public static void dumpTree(final Branch branch, final int level) {
        for (final Leaf leaf : branch.getLeaves()) {
            //信号
            dumpLeaf(leaf, level);
        }
        for (final Branch subBranch : branch.getBranches()) {
            //组
            dumpBranch(subBranch, level);
            //递归
            dumpTree(subBranch, level + 1);
        }
    }

    /**
     * 打印Item
     *
     * @param leaf
     */
    public static void dumpLeaf(final Leaf leaf, final int level) {
        System.out.println(printTab(level) + "Leaf: " + leaf.getName() + ":"
                + leaf.getItemId());
        //组名
        if (map.containsKey(leaf.getParent().getName())) {
            LinkedHashMap<String, String> itemLinkedHashMap = map.get(leaf.getParent().getName());
            //放信号 ,
            itemLinkedHashMap.put(leaf.getItemId(),"");
        }
    }

    /**
     * 打印Group
     *
     * @param branch
     */
    public static void dumpBranch(final Branch branch, final int level) {
        System.out.println(printTab(level) + "Branch: " + branch.getName());
        //实际上是该组名是二级目录 xianhe.设备 1；，所以需要多个if语句：这里假设items 有50个
        if ("设备 1".equals(branch.getName()) && !map.containsKey(branch.getName())) {
            LinkedHashMap<String, String> group = new LinkedHashMap<>(50);
            map.put(branch.getName(), group);
        }
//        else if(){}
    }

    private static String printTab(int level) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < level; i++) {
            sb.append("\t");
        }
        return sb.toString();
    }
}
